﻿#pragma once
#include <string>
#include <faac.h>
#include "CircleBuffer.h"

/**
 * 音频编码器
 */
class AACEncoder
{
public:
    AACEncoder();
    ~AACEncoder();

    /**
     * 打开编码器
     * 
     * @param sampleRateInHz 采样率
     * @param channelConfig  声道数
     */
    void open(int sampleRateInHz, int channelConfig);

    /**
     * 关闭编码器
     */
    void close();

    /**
     * 音频数据编码
     */
    int encodeAudioData(unsigned char* data, unsigned int size);

    /**
     * 获取音频解码信息
     */
    std::string audioDecodeInfo();

    /**
     * 获取输入样本个数
     */
    unsigned long inputSamples();

    /**
     * 获取编码输出缓冲区
     */
    unsigned char* faacEncodeOutputBuffer();

    /**
     * 获取 FAAC 最大输出字节个数
     */
    unsigned long maxOutputBytes();

private:

    /**
     * 音频通道数
     */
    int _channelConfig;

    /**
     * 输入样本个数, 需要进行编码的 PCM 音频样本个数
     * FAAC 编码器最多一次可以接收的样本个数
     * 传递下面两个数值的地址到 faacEncOpen 函数中, 用于当做返回值使用
     */
    unsigned long _inputSamples;

    /**
     * FAAC 最大输出字节个数
     * 传递下面两个数值的地址到 faacEncOpen 函数中, 用于当做返回值使用
     */
    unsigned long _maxOutputBytes;

    /**
     * PCM 音频 FAAC 编码器
     * 将 PCM 采样数据编码成 FAAC 编码器
     */
    faacEncHandle _faacEncHandle;

    /**
     * FAAC 编码输出缓冲区
     * FAAC 编码后的 AAC 裸数据, 存储到该缓冲区中
     * 该缓冲区在初始化 FAAC 编码器时创建
     */
    unsigned char* _faacEncodeOutputBuffer;

    /**
    * PCM 数据缓冲区，用于数据粘包。
    */
    CircleBuffer _pcmBuffer;
};